

/*
public class demo4 {
    public static void main(String[] args) throws InterruptedException {
        Object object = new Object();
        synchronized (object) {
            System.out.println("等待中");
            object.wait(1000);
            System.out.println("等待结束");
        }
    }
}*/


import java.util.TreeMap;

/*
public class demo4 {
    public static void main(String[] args) {
        //创建锁对象；
        Object locker = new Object();

        Thread t1 = new Thread(() -> {
            System.out.println("wait前");
            //在 synchronized 代码块中调用 wait 方法；
            synchronized (locker) {
                // wait 方法是由锁对象调用的，调用后，线程释放锁，进入等待队列；
                try {
                    locker.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("wait后");
        });
        t1.start();
        //抛出异常，清除中断标志，唤醒t1线程。
        t1.interrupt();
    }
}*/

public class demo4 {
    public static void main(String[] args) {
        Object locker = new Object();
        Thread t1 = new Thread(()->{
            System.out.println("t1!");
        });
        Thread t2 = new Thread(()->{
            try {
                t1.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("t2!");
        });
        Thread t3 = new Thread(()->{
            try {
                t2.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("t3!");
        });
        t3.start();
        t2.start();
        t1.start();
    }
 /*   public static void main(String[] args) {
        Object locker = new Object();
        Thread t1 = new Thread(()->{
            synchronized (locker) {
                System.out.println("t1");
                locker.notify(); // 通知 t2 执行
                try {
                    locker.wait();// 等待 t2 执行完毕
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        Thread t2 = new Thread(()->{
            synchronized (locker) {
                try {
                    locker.wait();// 等待 t1 执行完毕
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("t2");
                locker.notify();// 通知 t3 执行
            }
        });

        t1.start();
        t2.start();

    }*/
    /**
     * notifyAll()
     */
    public static void mai1n(String[] args) throws InterruptedException {
        Object locker = new Object();
        Thread t1 = new Thread(()->{
            System.out.println("t1 wait！");
            synchronized (locker) {
                try {
                    locker.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("t1 over!");
        });
        Thread t2 = new Thread(()->{
            System.out.println("t2 wait！");
            synchronized (locker) {
                try {
                    locker.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("t2 over!");
        });
        Thread t3 = new Thread(()->{
            System.out.println("t3 wait！");
            synchronized (locker) {
                try {
                    locker.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("t3 over!");
        });
        Thread t4 = new Thread(()->{
            synchronized (locker) {
                System.out.println("t4 唤起所有线程");
                locker.notifyAll();
            }
        });
        t1.start();
        t2.start();
        t3.start();
        Thread.sleep(1000);
        t4.start();
    }
    /**
     * notify()
     */
    public static void main22(String[] args) {
        //创建锁对象；
        Object locker = new Object();
        Thread t1 = new Thread(()->{
            System.out.println("t1 wait前！");
            synchronized (locker) {
                try {
                    locker.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("t1 wait后！");
        });

        Thread t2 = new Thread(()-> {
            try {
                Thread.sleep(1000);
                System.out.println("t2 notify 之前");
                //让 t1 线程有时间进入到wait状态
                synchronized (locker) {
                    locker.notify();
                    System.out.println("t2 notify 之后");
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        t1.start();
        t2.start();
    }
}